import { GameRoleCtrl } from './../game/GameCtrl';
import GameCtrl, { GameEvent } from "../game/GameCtrl";
import GameMapWidget from "../widget/game/GameMapWidget";
import GameControllerWidget from "../widget/game/ui/GameControllerWidget";
import GameRoleInfoWidget from "../widget/game/ui/GameRoleInfoWidget";
import BaseScene from "./BaseScene";
import GameTouchControllerWidget from '../widget/game/ui/GameTouchControllerWidget';

const {ccclass, property, menu} = cc._decorator;

@ccclass
@menu("Scene/GameScene")
export default class GameScene extends BaseScene {
    @property(GameMapWidget)
    mapWidget: GameMapWidget = null;

    @property(GameRoleInfoWidget)
    roleInfoWidget: GameRoleInfoWidget = null;

    //ui
    @property(GameControllerWidget)
    gameControllerWidget: GameControllerWidget = null;
    @property(GameTouchControllerWidget)
    gameTouchControllerWidget: GameTouchControllerWidget = null;

    @property(cc.Label)
    lb_tips: cc.Label = null;
    @property(cc.Node)
    node_win: cc.Node = null;
    @property(cc.Node)
    node_lose: cc.Node = null;
    
    private _events = [];

    onLoad(): void {
        super.onLoad();
        this.gameControllerWidget.onLoad();
        this.reset();
    }

    start(){
        GameCtrl.getInstance().init();
        GameCtrl.getInstance().signal.connect(this.onGameEventUpdate, this);
        this.schedule(this._gameUpdate.bind(this), 0, cc.macro.REPEAT_FOREVER);
        GameCtrl.getInstance().startGame(false);
    }

    private reset(){
        this.lb_tips.node.opacity = 0;
        this.node_win.active = false;
        this.node_lose.active = false;
        this.gameControllerWidget.stop();
        this.gameTouchControllerWidget.stop();
        this._events.length = 0;
    }

    private onGameEventUpdate(event: GameEvent, ...params){
        this._events.push({event: event, params: params, run: false});
    }

    private _gameUpdate(){
        this._checkControllerEvent();
        this._checkAndRunGameEvent();

        if(this._events.length == 0){
            this.mapWidget.roleStop();
        }
    }

    private _checkControllerEvent(){
        if(this._events.length > 0) return;

        let ctrl = this.gameControllerWidget.getCtrl();
        GameCtrl.getInstance().roleMove(ctrl);
        
        if(this._events.length > 0) return;

        let pos = this.gameTouchControllerWidget.getNextPoint();
        if(pos != null){
            let ret = GameCtrl.getInstance().roleMoveTo(pos);
            if(!ret){
                this.gameTouchControllerWidget.clear();
            }
        }
    }

    private async _checkAndRunGameEvent(){
        if(this._events.length == 0 || this._events[0].run) return;

        let event = this._events[0];
        event.run = true;
        await this._runGameEvent(event);
        this._events.splice(0, 1);
    }

    private async _runGameEvent(event){
        let eventType = event.event;
        let params = event.params;
        let ret = null;
        switch(eventType){
            case GameEvent.GAME_START: {
                this.roleInfoWidget.init();
            }
                break;

            case GameEvent.GAME_END: {
                //显示结算
                let isWin = params[0];
                if(isWin){
                    this.node_win.active = true;
                }else{
                    this.node_lose.active = true;
                }
                this.gameControllerWidget.stop();
                this.gameTouchControllerWidget.stop();
            }
                break;

            case GameEvent.MAP_ENTER: {
                ret = await this.mapWidget.init();
                this.gameControllerWidget.init();
                this.gameTouchControllerWidget.init();
            }
                break;

            case GameEvent.MAP_EXIT: {
                this.gameControllerWidget.stop();
                this.gameTouchControllerWidget.stop();
                ret = await this.mapWidget.exit();
            }
                break;
                
            case GameEvent.BAG_UPDATE: {
                this.roleInfoWidget.updateBag();
            }
                break;

            case GameEvent.MAP_UPDATE: {
                this.mapWidget.refresh(true);
            }
                break;

            case GameEvent.KEY_NOT_ENOUGH: {
                //提示钥匙不足
                this._showTips("钥匙不足");
            }
                break;

            case GameEvent.ROLE_MOVE: {
                //角色移动
                ret = await this.mapWidget.roleMove(params[0]);
            }
                break;

            case GameEvent.ROLE_ATTACK: {
                ret = await this.mapWidget.roleAction("attack", params)
            }
                break;

            case GameEvent.ROLE_DEAD: {
                ret = await this.mapWidget.roleAction("dead", params);
            }
                break;


            case GameEvent.ROLE_UPDATE: {
                this.mapWidget.roleUpdate();
            }
                break;

            case GameEvent.MONSTER_ATTACK: {
                ret = await this.mapWidget.monsterAction("attack", params);
            }
                break;

            case GameEvent.MONSTER_DEAD: {
                ret = await this.mapWidget.monsterAction("dead", params);
            }
                break;
        }
        return ret;
    }

    private onNext(){
        //跳过
        (window as any).isClosed = true;
        window.close();
    }

    private onRestart(){
        //重新开始
        this.reset();
        GameCtrl.getInstance().startGame(true);
    }

    private _showTips(tips: string){
        this.lb_tips.string = tips;
        this.lb_tips.getComponent(cc.Animation).play();
    }
}